import React, { useState, useEffect } from 'react'
import { Button, Space, Form, Input, Card, Select, Table, message } from 'antd'
import { SearchOutlined } from '@ant-design/icons'
import type { ColumnsType } from 'antd/es/table'
import { useNavigate } from 'react-router-dom'
import {
  reqGetHospitalList,
  reqGetProvince,
  reqGetCityOrDistrictOrHostype,
  reqUpdateHosStatus,
} from '@api/hospitalList'
import {
  IhosList,
  IhosItem,
  IdicList,
} from '@api/hospitalList/model/hospitalListTypes'

// 解构Select组件中的Option组件
const { Option } = Select
let flag = false
export default function HospitalList() {
  const navigate = useNavigate()
  const [form] = Form.useForm()
  // 分页相关的状态
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(5)
  const [total, setTotal] = useState(0)
  // 存储表格数据的状态
  const [hosList, setHosList] = useState<IhosList>([])
  // 省状态
  const [province, setProvince] = useState<IdicList>([])
  // 市状态
  const [city, setCity] = useState<IdicList>([])
  // 区状态
  const [district, setDistrict] = useState<IdicList>([])
  // 医院类型状态
  const [hostype, setHostype] = useState<IdicList>([])

  // 四个下拉框的loading效果
  const [provinceLoading, setProvinceLoading] = useState(false)
  const [cityLoading, setCityLoading] = useState(false)
  const [disLoading, setDisLoading] = useState(false)
  const [typeLoading, setTypeLoading] = useState(false)

  // 表格的loading
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    // 获取表格数据
    getHospitalList(page, pageSize)
    // 获取省数据
    getProvince()

    // 获取医院类型
    getHostype('10000')
  }, [])

  const onFinish = (values: any) => {
    // 将flag设置为true,表示要添加筛选条件
    flag = true
    getHospitalList(1, pageSize)
    setPage(1)
  }
  // Table组件渲染数据时,需要知道要渲染的数组中的数据对象是什么类型,所以要求我们将数据对象类型,通过泛型传入ColumnsType即可
  const columns: ColumnsType<IhosItem> = [
    // columns中一个对象,代表一列. 每一个对象中写的配置项,可以控制这一列要渲染什么数据
    {
      title: '序号', // 这一列的标题
      // render的返回值是什么,则这一列就渲染什么
      render(a, b, index) {
        return index + 1
      },
      // 让这一列的文本水平居中
      align: 'center',
    },
    {
      title: '医院logo',
      render(a, hos, index) {
        return (
          <img
            // 注意: 服务器相应的图片是base64格式,并且base64的字符串还不完整.所以需要我们自己拼接前面一部分的字符串
            src={'data:image/png;base64,' + hos.logoData}
            alt=""
            width="80"
          />
        )
      },
    },
    {
      title: '医院名称',
      // 没写render,则由dataIndex决定这一列渲染什么
      // 写了render,则dataIndex就不能决定这一列渲染什么了,而是决定render的第一个形参接受到什么
      dataIndex: 'hosname',
    },
    {
      title: '等级',
      // 注意: dataIndex中只能写数据对象中的直接属性.嵌套的属性写了也解析不了
      // dataIndex: 'param.hostypeString',
      render(hos) {
        return hos.param.hostypeString
      },
    },
    {
      title: '详细地址',
      render(hos) {
        return hos.param.fullAddress
      },
    },
    {
      title: '状态',
      dataIndex: 'status',
      render(status) {
        return status ? '已上线' : '未上线'
      },
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
    },
    {
      title: '操作',
      render(hos) {
        return (
          <Space>
            <Button
              type="primary"
              onClick={() => {
                navigate(`/syt/hospital/hospitallist/show/${hos.id}`)
              }}
            >
              查看
            </Button>
            <Button
              type="primary"
              onClick={() => {
                navigate('/syt/hospital/hospitallist/schedule', {
                  state: { hoscode: hos.hoscode, hosname: hos.hosname },
                })
              }}
            >
              排班
            </Button>
            <Button
              type="primary"
              onClick={async () => {
                await reqUpdateHosStatus(hos.id, hos.status ? 0 : 1)
                message.success(hos.status ? '下线成功' : '上线成功')
                // 更新数据
                getHospitalList(page, pageSize)
              }}
            >
              {!hos.status ? '上线' : '下线'}
            </Button>
          </Space>
        )
      },
      width: 180, // 控制这一列的宽度
    },
  ]

  // 获取表格数据封装的函数
  async function getHospitalList(page: number, pageSize: number) {
    setLoading(true)
    // 由于在多个请求表格数据的地方都需要判断是否添加筛选参数,所以干脆将判断写在这个函数中.判断条件就是flag是否为true
    let result
    // 进行判断,是否要添加筛选条件获取表格数据
    if (flag) {
      const params = form.getFieldsValue()
      result = await reqGetHospitalList({ page, limit: pageSize, ...params })
    } else {
      result = await reqGetHospitalList({ page, limit: pageSize })
    }

    //将表格数据存储到状态中
    setHosList(result.content)
    //将数据总数存储到状态中
    setTotal(result.totalElements)
    setLoading(false)
  }

  // 获取省数据
  async function getProvince() {
    setProvinceLoading(true)
    const result = await reqGetProvince('province')
    // console.log(result)
    setProvince(result)
    setProvinceLoading(false)
  }

  // 获取市数据
  async function getCity(id: string) {
    setCityLoading(true)
    const result = await reqGetCityOrDistrictOrHostype(id)
    setCity(result)
    setCityLoading(false)
  }
  // 获取区数据
  async function getDistrict(id: string) {
    setDisLoading(true)
    const result = await reqGetCityOrDistrictOrHostype(id)
    setDistrict(result)
    setDisLoading(false)
  }
  // 获取区数据
  async function getHostype(id: string) {
    setTypeLoading(true)
    const result = await reqGetCityOrDistrictOrHostype(id)
    setHostype(result)
    setTypeLoading(false)
  }
  return (
    <Card>
      <Form
        name="basic"
        onFinish={onFinish}
        layout="inline"
        form={form}
        onValuesChange={() => {
          // 只要表单被修改,必须点击查询,才会增加筛选条件查询.否则不应该添加筛选条件
          flag = false
        }}
      >
        <Form.Item name="provinceCode">
          <Select
            loading={provinceLoading}
            placeholder="请选择省"
            style={{ width: 200, marginBottom: 20 }}
            onChange={(key) => {
              //清空市和区的值
              form.setFieldsValue({
                cityCode: undefined,
                districtCode: undefined,
              })
              // 当用户选中下拉框中的某个option.则onchange会触发.并传入选中的option的value值和其他数据对象
              // 发送请求获取市数据
              getCity(key)
            }}
          >
            {province.map((item) => {
              return (
                <Option key={item.id} value={item.value}>
                  {item.name}
                </Option>
              )
            })}
          </Select>
        </Form.Item>
        <Form.Item name="cityCode">
          <Select
            loading={cityLoading}
            placeholder="请选择市"
            style={{ width: 200 }}
            onChange={(key) => {
              //清空区的值
              form.setFieldsValue({
                districtCode: undefined,
              })
              getDistrict(key)
            }}
          >
            {city.map((item) => {
              return (
                <Option key={item.id} value={item.value}>
                  {item.name}
                </Option>
              )
            })}
          </Select>
        </Form.Item>
        <Form.Item name="districtCode">
          <Select
            loading={disLoading}
            placeholder="请选择区"
            style={{ width: 200 }}
          >
            {district.map((item) => {
              return (
                <Option key={item.id} value={item.value}>
                  {item.name}
                </Option>
              )
            })}
          </Select>
        </Form.Item>
        <Form.Item name="hosname">
          <Input placeholder="医院名称"></Input>
        </Form.Item>
        <Form.Item name="hoscode">
          <Input placeholder="医院编码"></Input>
        </Form.Item>
        <Form.Item name="hostype">
          <Select
            loading={typeLoading}
            placeholder="医院类型"
            style={{ width: 200, marginBottom: 20 }}
          >
            {hostype.map((item) => {
              return (
                <Option key={item.id} value={item.value}>
                  {item.name}
                </Option>
              )
            })}
          </Select>
        </Form.Item>
        <Form.Item name="status">
          <Select placeholder="医院状态" style={{ width: 200 }}>
            {/* value="0"这样是字符串0. value={0}这样是数字0 */}
            <Option value={0}>未上线</Option>
            <Option value={1}>已上线</Option>
          </Select>
        </Form.Item>

        <Form.Item>
          <Space>
            <Button type="primary" htmlType="submit" icon={<SearchOutlined />}>
              查询
            </Button>
            <Button
              onClick={() => {
                // 清空表单
                // 由于表单中每一个表单项默认初始值都是undefined.而resetFields就是让表单中每一个表单元素恢复到初始值.所以只要重置表单,就可以达到和清空表单相同的效果
                form.resetFields()
                // flag = false
                flag = false
                // 请求表格数据
                getHospitalList(1, pageSize)
                setPage(1)
              }}
            >
              清空
            </Button>
          </Space>
        </Form.Item>
      </Form>
      <Table
        loading={loading}
        columns={columns}
        dataSource={hosList}
        rowKey="id"
        // pagination用来控制表格的分页器
        pagination={{
          // 控制分页器中哪个页码高亮
          current: page,
          // 告诉分页器总共有多少条数据
          total,
          // 决定一页展示几条数据. 默认值是10
          pageSize,
          // 展示选择一页几条的下拉框
          showSizeChanger: true,
          // 控制下拉框的里面的选项
          pageSizeOptions: [2, 5, 10],
          // 展示快速跳转
          showQuickJumper: true,
          // 在分页器前面展示文本
          showTotal(total) {
            return `总共: ${total}`
          },
          // 当用户想要改变页码或者改变一页几条(点击分页器)
          onChange(page, pageSize) {
            // page就是用户选中的那个页码
            // pageSize就是用户选中的那个一页几条
            setPage(page)
            setPageSize(pageSize)
            // 一旦用户点击了分页器,我们需要重新给服务器发送请求,获取表格数据
            // 注意: setXxx是异步的.所以刚刚调用完之后数据其实还没有变化,所以在getHospitalList中拿到的状态page和pageSize的值不是最新的页码和一页几条.还是得将最新的数据通过函数的参数,传递给getHospitalList
            getHospitalList(page, pageSize)
          },
        }}
      ></Table>
    </Card>
  )
}
